package Project;

import java.util.ArrayList;

import javax.swing.JTextArea;

import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.time.SimpleTimePeriod;

public class Processor {
	final int NumProcessorStates = 500;
	private int processorID;
	private ArrayList<SingleTask> lastTaskScheduled = new ArrayList<SingleTask>();
	private tuple[] states = new tuple[NumProcessorStates];
	
	public Processor( int pid )
	{
		for(int i = 0; i< NumProcessorStates; i++ )
		{
			states[i] = new tuple(ProcessorStates.FREE, new SingleTask()) ;
		}
		processorID = pid;
	}
	public void populateTaskSeries( TaskSeries t )
	{
		int startindex = -1;
		int endindex = -1;
		
		for(int i = 0; i< getEarliestAvailableTime()+1; i++)
		{
			if(states[i].state == ProcessorStates.BUSY)
			{
				if(startindex == -1)
				{
					if( i > 0 )
						startindex = i-1;
					else
						startindex = i;

				}
			}

			if(states[i].state == ProcessorStates.ENDOFTASK)
			{
				endindex = i;
				t.add(new Task( ("T"+ states[i].task.getTaskId() ), new SimpleTimePeriod(startindex,endindex) ) );
				if(states[i].newTask.getTaskId() != -1 )
				{
					startindex = i;
					endindex = -1;
				}
				else
					startindex = -1;
			}
		}
	}
	public boolean Schedule(int start, int end, SingleTask t)
	{
		if(start < 0 || start > 99 || end < 0 || end > 99 || start > end )
			return false;
		if(start == 0)
			states[0] = new tuple( ProcessorStates.BUSY, t);

		states[start].newTask = t;
		for (int i = start + 1; i < end; i++)
		{
			if(states[i].state != ProcessorStates.ENDOFTASK)
			{
				states[i] = new tuple( ProcessorStates.BUSY, t);
			}

		}
		states[end] = new tuple(ProcessorStates.ENDOFTASK, t);
		lastTaskScheduled.add(t);
		return true;
	}
	public int getEarliestAvailableTime()
	{
		int last = 0;
		for(int i = 0; i< NumProcessorStates; i++ )
		{
			if(states[i].state == ProcessorStates.ENDOFTASK || states[i].state == ProcessorStates.BUSY )
				last = i;
		}
		return last;
	}
	public SingleTask getTaskAtTime(int time)
	{
		return states[time].task;
	}
	public boolean isAvailable( int time )
	{
		if(states[time].state == ProcessorStates.ENDOFTASK || states[time].state == ProcessorStates.FREE)
			return true;
		else
			return false;
	}/*
	public boolean Backtrack (SingleTask t)
	{
		boolean backtracked = false;
		for(int i = 0; i< NumProcessorStates; i++ )
		{
			if(states[i].task.getTaskId() == t.getTaskId())
			{
				if(!backtracked)
					states[i-1].newTask = new SingleTask();
				
				backtracked = true;
				states[i].state = ProcessorStates.FREE;
				states[i].task = new SingleTask();
			}
			states[i] = new tuple(ProcessorStates.FREE, new SingleTask()) ;
		}
		return backtracked;
	}*/
	public SingleTask Backtrack( JTextArea textArea )
	{
		boolean backtracked = false;
		textArea.append("BackTracking Task T" + lastTaskScheduled.get(lastTaskScheduled.size()-1).getTaskId() + "\n" );
		for(int i = 0; i< NumProcessorStates; i++ )
		{
			if(states[i].task.getTaskId() == lastTaskScheduled.get(lastTaskScheduled.size()-1).getTaskId())
			{
				if(!backtracked)
					states[i-1].newTask = new SingleTask();
				
				backtracked = true;
				states[i].state = ProcessorStates.FREE;
				states[i].task = new SingleTask();
			}
		}
		return lastTaskScheduled.remove(lastTaskScheduled.size()-1);
	}
	public int getProcessorID()
	{
		return processorID;
	}


	private class tuple{
		public ProcessorStates state;
		public SingleTask task;
		public SingleTask newTask;
		public tuple( ProcessorStates pstate, SingleTask t) 
		{
			task = t;
			state = pstate;
			newTask = new SingleTask();
		}
	}
}
